﻿using Common.AspNetCore;
using Common.Infrastructure;
using File.Api.Models;
using File.Api.Repository;
using File.Api.Utils;
using File.Data.Entity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace File.Api.Service
{
    public class DownloadFileService : CommonService
    {
        private readonly FileRepository fileRepository;

        public DownloadFileService(IServiceProvider provider, FileRepository file) : base(provider)
        {
            this.fileRepository = file;
        }

        public async Task<DownFileModel> DownloadFileAsync(List<string> ids)
        {
            DownFileModel ret = new DownFileModel();
            try
            {
                var r = await this.fileRepository.GetFilesByIdsAsync(ids);
                if (r == null || !r.Any())
                {
                    return null;
                }

                List<t_file> list = new List<t_file>();
                list.AddRange(r);
                var s = await DownloadFileAsync(list);
                if (s != null && s.Any())
                {
                    ret.Details.AddRange(s);
                }
            }
            catch (Exception ex)
            {
                /////this.ThrowError("06900001", ex.Message);
            }

            return ret;
        }

        public async Task<DownFileGroupModel> DownloadFileGroupAsync(List<string> ids)
        {
            DownFileGroupModel ret = new DownFileGroupModel();
            try
            {
                var r = await this.GetFileGroupDbModelAsync(ids);
                if (r == null)
                {
                    return null;
                }

                var s = await DownloadFileAsync(r.Files);
                foreach (var fg in r.FileGroups)
                {
                    var df = !string.IsNullOrEmpty(fg.file_id) ? s.FirstOrDefault(t => t.FileId == fg.file_id) : null;
                    var d = new DownFileGroupDetailModel()
                    {
                        FileGroupId = fg.id,
                        CreateTime = fg.create_time,
                        FileId = fg.file_id,
                        FileName = fg.file_name,
                        FileType = fg.file_type,
                        UserName = fg.user_name,
                    };
                    if (df != null)
                    {
                        d.FileData = df.FileData;
                        d.FileLength = df.FileLength;
                        d.FilePath = df.FilePath;
                    }

                    r.FileGroupDetails.Where(t => t.file_group_id == fg.id).OrderBy(t => t.index).ForEach(t =>
                    {
                        var df1 = !string.IsNullOrEmpty(t.file_id) ? s.FirstOrDefault(t1 => t1.FileId == t.file_id) : null;
                        if (df1 != null)
                        {
                            d.Details.Add(df1);
                        }
                    });
                    ret.Details.Add(d);
                }
            }
            catch (Exception ex)
            {
                ////this.ThrowError("06900001", ex.Message);
            }

            return ret;
        }

        public async Task<List<DownFileDetailModel>> DownloadFileAsync(List<t_file> list)
        {
            List<DownFileDetailModel> files = new List<DownFileDetailModel>();
            foreach (var r in list)
            {
                var s = new DownFileDetailModel()
                {
                    FileId = r.id,
                    FileType = r.file_type,
                    FileName = r.file_name,
                    FilePath = r.file_path,
                    CreateTime = r.create_time,
                    UserName = r.user_name
                };
                if (s.FilePath.StartsWith("ftp"))
                {
                    await FtpFileUtils.DownloadFileAsync(s);
                }
                else
                {
                    await LocalFileUtils.DownloadFileAsync(s);
                }

                files.Add(s);
            }

            return files;
        }

        private async Task<FileGroupDbModel> GetFileGroupDbModelAsync(List<string> ids)
        {
            FileGroupDbModel ret = new FileGroupDbModel();
            var orderModel = await this.fileRepository.GetFileGroupOrderByIdsModelAsync(ids); 
            var filegroups = orderModel?.FileGroups;
            if (filegroups == null || !filegroups.Any())
            {
                return null;
            }

            var r1 = orderModel.FileGroupDetails;
            List<string> fileIds = new List<string>();
            fileIds.AddRange(filegroups.Where(t => !string.IsNullOrEmpty(t.file_id)).Select(t => t.file_id));
            if (r1 != null && r1.Any())
            {
                fileIds.AddRange(r1.Select(t => t.file_id));
            }

            IEnumerable<t_file> files = null;
            if (fileIds.Any())
            {
                files = await this.fileRepository.GetFilesByIdsAsync(fileIds);
            }

            ret.FileGroups.AddRange(filegroups);
            if (r1.Any())
            {
                ret.FileGroupDetails.AddRange(r1);
            }

            if (files != null && files.Any())
            {
                ret.Files.AddRange(files);
            }

            return ret;
        }
    }
}
